package com.aliyun.www.sync;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.aliyun.www.sync.core.Sign;
import com.aliyun.www.sync.core.Verify;

import java.util.*;

/**
 * @author kyle
 * @date 2018/08/17
 */
public class Signature {

    public static Map<String, Object> outputJson(Map<String, Object> map, String privateKey) {
        return outputJson(map, privateKey,"SHA256WithRSA");
    }

    public static Map<String, Object> outputJson(Map<String, Object> map, String privateKey,  String signatureMethod) {
        if (map == null) {
            throw new NullPointerException();
        }
        String serializedStr = generateSerializeStrFromMap(map);
        System.out.println("需要签名的序例串:"+serializedStr);
        String signStr = Sign.sign(serializedStr, privateKey);
        System.out.println("签名值:"+signStr);
        map.put("signature", signStr );
        map.put("signatureMethod", signatureMethod);
        return map;
    }

    public static boolean verifyPacket(String packet, String pubKey) {
        Map<String, Object> map = JSON.parseObject(packet);
        String signature = ((JSONObject)map).getString("signature");
        String signatureMethod = ((JSONObject)map).getString("signatureMethod");
        String serializedStr = generateSerializeStrFromMap(map);
        return Verify.verify(serializedStr, signature, signatureMethod, pubKey);
    }

    private static String generateSerializeStrFromMap(Map<String, Object> map) {
        Map<String, String> serializedValueMap = serializeValueOfMap(map);
        serializedValueMap.remove("signature");
        serializedValueMap.remove("signatureMethod");
        StringBuilder content = new StringBuilder();
        List<String> keys = new ArrayList<String>(serializedValueMap.keySet());
        Collections.sort(keys);
        int index = 0;
        for (int i = 0; i < keys.size(); i++) {
            String key = keys.get(i);
            String value = serializedValueMap.get(key);
            if (!StringUtils.isEmpty(key) && !StringUtils.isEmpty(value)) {
                content.append((index == 0 ? "" : "&") + key + "=" + value);
                index++;
            }
        }
        return content.toString();

    }

    private static Map<String, String> serializeValueOfMap(Map<String, Object> map) {
        Map<String, String> result = new HashMap<String, String>(map.size());
        for (Map.Entry<String, Object> entity : map.entrySet()) {
            if (entity.getValue() != null) {
                result.put(entity.getKey(), String.valueOf(entity.getValue()));
            }
        }
        return result;
    }
}
